#! /usr/bin/env python
# -*- coding:utf-8 -*-
# @Time : 2020-04-06 22:59
# @Author : youngchaolin

# 1 默认参数的陷阱
def func(name, gender='男'):
    print(name)
    print(gender)


func('alex')


# 陷阱只针对默认参数是可变的数据类型
def func(name, li=[]):
    li.append(name)
    return li


ret = func('alex')
print(ret)
ret_2 = func('messi')
print(ret_2)

'''
如果默认参数，指向的是可变的数据类型，无论调用多少次，这个默认参数在内存中都是同一个
'''


def func(a, li=[]):
    li.append(a)
    return li

# 参数传了[]，就用以前的，否则就使用新的
# print(func(10,)) # [10]
# print(func(20,[])) # [20] # 参数传了就用新的列表
# print(func(100,)) #[10,100] 参数没传就用以前的列表

ret_1 = func(10, )
ret_2 = func(20, [])
ret_3 = func(100, )

# 如果先执行完，再一一打印，就是这个结果，坑太多，有啥用呢？难道我还写代码会经常想这个吗
print(ret_1)  # [10,100]
print(ret_2)  # [20]
print(ret_3)  # [10,100]

# 2 局部作用域的坑
count = 0

def func():
    print(count)  # 报错 local variable 'count' referenced before assignment，程序走到这里就会从局部找
    # 把这个注释掉，上面的错就不会报了，不会给解释器造成困扰，如果定义了解释器就蒙圈了，不知道你到底要使用局部的还是全局的
    # count=1

func()

'''
在函数中如果定义一个变量，但是在定义这个变量之前，就先对它引用了，则会报上面的错，python解释器会认为是语法问题
'''

# global
# 1 在局部声明一个全局变量

# name='alex'
#
# def func():
#     name='messi'
#     print(name)
#
# func()
# print(name)

def func():
    global name
    name='messi'
    print(name)
# 1 print放在func前会报错
# print(name)
func()
# 2 print放在func后不会报错
# print(name)

# 验证是否是全局，下面的方法可以打印出当前作用域的所有全局变量
print(globals())

# 2 可以在局部修改一个全局变量
count=0

def func():
    global count
    count+=1

print(count)
func()
print(count)

# nonlocal python3.4后更新
# 1 不容许操作全局变量

# 2 内层函数可以对外层函数的局部变量进行修改
def outer():
    count=0
    def inner():
        # 这里依然不能直接修改，内层函数不能修改外层函数的局部变量，使用nonlocal可以解决
        nonlocal count
        count+=1
    print('inner函数执行前：%d'%(count,))
    inner()
    print('inner函数执行后：%d'%(count,))

outer()





